export default class CollisionGrid {
    private _checks: Array<cc.Node>;//用于保存需要碰撞检测的对象(注：Vector.<T>相当于c#中的泛型数组)
    private _grid: Array<Array<cc.Node>>;//网格(注：这里用“一维数组套一维数组”的方法替代了原来的二维数组)
    private _gridSize: number;
    private _height: number;
    private _numCells: number;
    private _numCols: number;
    private _numRows: number;
    private _width: number;
    private offsetX:number;//坐标问题
    private offsetY:number;//坐标问题
    constructor(width: number, height: number, gridSize: number) {
        this._width = width;
        this._height = height;
        this._gridSize = gridSize;

        this._numCols = Math.ceil(width / gridSize);//计算总列数            
        this._numRows = Math.ceil(height / gridSize);//计算总行数
        this._numCells = this._numCols * this._numRows;//单元格总数
        var size = cc.view.getVisibleSize();
        this.offsetX=size.width*0.5
        this.offsetY=size.height*0.5
    }
    //将需要检测的对象(泛型)数组objects分配到网络
    public assign(objects) {
        var numObjects: number = objects.length;
        this._grid = [];
        this._checks = [];
        for (var i: number = 0; i < numObjects; i++) {
            var obj: cc.Node = objects[i];
           var tx=obj.x+this.offsetX
           var ty=obj.y+this.offsetY
            //注意：这里用“Grid.[索引]”（定位）的方式，替换了原来的“Grid.[列][行]”（单元格的定位）方式--回想一下bitmap位图中的像素索引就更容易理解了
            var index: number = Math.floor(ty / this._gridSize) * this._numCols + Math.floor(tx / this._gridSize);
            //“单元格”--延时实例化"
            if (this._grid[index] == null) {
                this._grid[index] = [];
            }
            //将对象推入"单元格"
            this._grid[index].push(obj);
        }

        //检测需要碰撞的对象，并保存到_checks数组
        this.checkGrid();
    }

    //"单元格"检测
    private checkGrid(): void {
        for (var i: number = 0; i < this._numCols; i++) {
            for (var j: number = 0; j < this._numRows; j++) {
                this.checkOneCell(i, j);
                this.checkTwoCells(i, j, i + 1, j);
                this.checkTwoCells(i, j, i - 1, j + 1);
                this.checkTwoCells(i, j, i, j + 1);
                this.checkTwoCells(i, j, i + 1, j + 1);
            }
        }
    }

    //(自身)单个单元格的检测
    private checkOneCell(x: number, y: number): void {
        var cell: Array<cc.Node> = this._grid[y * this._numCols + x];
        if (cell == null) {
            return;
        }
        var cellLength: number = cell.length;

        for (var i: number = 0; i < cellLength - 1; i++) {
            var objA: cc.Node = cell[i];
            for (var j: number = i + 1; j < cellLength; j++) {
                var objB: cc.Node = cell[j];
                this._checks.push(objA, objB);
            }
        }
    }

    //单元格(x1,y1)与单元格(x2,y2)的检测
    private checkTwoCells(x1: number, y1: number, x2: number, y2: number): void {
        if (x2 >= this._numCols || x2 < 0 || y2 >= this._numRows) {
            return;
        }
        var cellA = this._grid[y1 * this._numCols + x1];
        var cellB = this._grid[y2 * this._numCols + x2];
        if (cellA == null || cellB == null) {
            return;
        }
        var cellALength: number = cellA.length;
        var cellBLength: number = cellB.length;
        for (var i: number = 0; i < cellALength; i++) {
            var objA: cc.Node = cellA[i];
            for (var j: number = 0; j < cellBLength; j++) {
                var objB: cc.Node = cellB[j];
                this._checks.push(objA, objB);
            }
        }
    }

    public get checks() {
        return this._checks;
    }
    // update (dt) {}
}
